home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / mus / misc / mpegaudiofix.lha / musicout.c < prev   
C/C++ Source or Header  |  1995-03-30  |  19KB  |  480 lines

  1. /**********************************************************************
  2. Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reserved
  3. musicout.c
  4. **********************************************************************/
  5. /**********************************************************************
  6.  * MPEG/audio coding/decoding software, work in progress              *
  7.  *   NOT for public distribution until verified and approved by the   *
  8.  *   MPEG/audio committee.  For further information, please contact   *
  9.  *   Davis Pan, 508-493-2241, e-mail: pan@3d.enet.dec.com             *
  10.  *                                                                    *
  11.  * VERSION 3.9                                                        *
  12.  *   changes made since last update:                                  *
  13.  *   date   programmers                comment                        *
  14.  * 2/25/91  Douglas Wong        start of version 1.0 records          *
  15.  * 3/06/91  Douglas Wong        rename setup.h to dedef.h             *
  16.  *                              removed extraneous variables          *
  17.  *                              removed window_samples (now part of   *
  18.  *                              filter_samples)                       *
  19.  * 3/07/91  Davis Pan           changed output file to "codmusic"     *
  20.  * 5/10/91  Vish (PRISM)        Ported to Macintosh and Unix.         *
  21.  *                              Incorporated new "out_fifo()" which   *
  22.  *                              writes out last incomplete buffer.    *
  23.  *                              Incorporated all AIFF routines which  *
  24.  *                              are also compatible with SUN.         *
  25.  *                              Incorporated user interface for       *
  26.  *                              specifying sound file names.          *
  27.  *                              Also incorporated user interface for  *
  28.  *                              writing AIFF compatible sound files.  *
  29.  * 27jun91  dpwe (Aware)        Added musicout and &sample_frames as  *
  30.  *                              args to out_fifo (were glob refs).    *
  31.  *                              Used new 'frame_params' struct.       *
  32.  *                              Clean,simplify, track clipped output  *
  33.  *                              and total bits/frame received.        *
  34.  * 7/10/91  Earle Jennings      changed to floats to FLOAT            *
  35.  *10/ 1/91  S.I. Sudharsanan,   Ported to IBM AIX platform.           *
  36.  *          Don H. Lee,                                               *
  37.  *          Peter W. Farrett                                          *
  38.  *10/ 3/91  Don H. Lee          implemented CRC-16 error protection   *
  39.  *                              newly introduced functions are        *
  40.  *                              buffer_CRC and recover_CRC_error      *
  41.  *                              Additions and revisions are marked    *
  42.  *                              with "dhl" for clarity                *
  43.  * 2/11/92  W. Joseph Carter    Ported new code to Macintosh.  Most   *
  44.  *                              important fixes involved changing     *
  45.  *                              16-bit ints to long or unsigned in    *
  46.  *                              bit alloc routines for quant of 65535 *
  47.  *                              and passing proper function args.     *
  48.  *                              Removed "Other Joint Stereo" option   *
  49.  *                              and made bitrate be total channel     *
  50.  *                              bitrate, irrespective of the mode.    *
  51.  *                              Fixed many small bugs & reorganized.  *
  52.  *19 aug 92 Soren H. Nielsen    Changed MS-DOS file name extensions.  *
  53.  * 8/27/93 Seymour Shlien,      Fixes in Unix and MSDOS ports,        *
  54.  *         Daniel Lauzon, and                                         *
  55.  *         Bill Truerniet                                             *
  56.  **********************************************************************/
  57.  
  58. #include        "common.h"
  59. #include        "decoder.h"
  60.  
  61. #ifdef UNIX
  62. #include <time.h>
  63. #endif
  64.  
  65. /********************************************************************
  66. /*
  67. /*        This part contains the MPEG I decoder for Layers I & II.
  68. /*
  69. /*********************************************************************/
  70.  
  71. /****************************************************************
  72. /*
  73. /*        For MS-DOS user (Turbo c) change all instance of malloc
  74. /*        to _farmalloc and free to _farfree. Compiler model hugh
  75. /*        Also make sure all the pointer specified are changed to far.
  76. /*
  77. /*****************************************************************/
  78.  
  79. /*********************************************************************
  80. /*
  81. /* Core of the Layer II decoder.  Default layer is Layer II.
  82. /*
  83. /*********************************************************************/
  84.  
  85.  
  86. /*
  87.  *
  88.  * The call to aiff_write_headers() has been changed to pass the
  89.  * filename.  This was done so that the file could be closed and opened
  90.  * in append mode instead of doing an fseek().  Fseek() is faulty for
  91.  * SAS/C.
  92.  * 
  93.  * Dan Oberlin
  94.  *
  95.  */
  96.  
  97. /* Global variable definitions for "musicout.c" */
  98.  
  99. char *programName;
  100.  
  101. /* Implementations */
  102.  
  103. main(argc, argv)
  104. int argc;
  105. char **argv;
  106. {
  107. typedef short PCM[2][3][SBLIMIT];
  108.     PCM FAR *pcm_sample;
  109. typedef unsigned int SAM[2][3][SBLIMIT];
  110.     SAM FAR *sample;
  111. typedef double FRA[2][3][SBLIMIT];
  112.     FRA FAR *fraction;
  113. typedef double VE[2][HAN_SIZE];
  114.     VE FAR *w;
  115.  
  116.     Bit_stream_struc  bs;
  117.     frame_params      fr_ps;
  118.     layer             info;
  119.     FILE              *musicout;
  120.     unsigned long     sample_frames;
  121.  
  122.     int               i, j, k, stereo, done=FALSE, clip, sync;
  123.     int               error_protection, crc_error_count, total_error_count;
  124.     unsigned int      old_crc, new_crc;
  125.     unsigned int      bit_alloc[2][SBLIMIT], scfsi[2][SBLIMIT],
  126.                       scale_index[2][3][SBLIMIT];
  127.     unsigned long     bitsPerSlot, samplesPerFrame, frameNum = 0;
  128.     unsigned long     frameBits, gotBits = 0;
  129.     IFF_AIFF          pcm_aiff_data;
  130.     char              encoded_file_name[MAX_NAME_SIZE];
  131.     char              decoded_file_name[MAX_NAME_SIZE];
  132.     char              t[50];
  133.     int               need_aiff;
  134.     int topSb = 0;
  135.  
  136. #ifdef UNIX
  137.     clock_t time_to_decode = clock();
  138. #endif
  139.  
  140. #ifdef  MACINTOSH
  141.     console_options.nrows = MAC_WINDOW_SIZE;
  142.     argc = ccommand(&argv);
  143. #endif
  144.  
  145.     /* Most large variables are declared dynamically to ensure
  146.        compatibility with smaller machines */
  147.  
  148.     pcm_sample = (PCM FAR *) mem_alloc((long) sizeof(PCM), "PCM Samp");
  149.     sample = (SAM FAR *) mem_alloc((long) sizeof(SAM), "Sample");
  150.     fraction = (FRA FAR *) mem_alloc((long) sizeof(FRA), "fraction");
  151.     w = (VE FAR *) mem_alloc((long) sizeof(VE), "w");
  152.  
  153.     fr_ps.header = &info;
  154.     fr_ps.tab_num = -1;                /* no table loaded */
  155.     fr_ps.alloc = NULL;
  156.     for (i=0;i<HAN_SIZE;i++) for (j=0;j<2;j++) (*w)[j][i] = 0.0;
  157.  
  158.     programName = argv[0];
  159.     if(argc==1) {        /* no command line args -> interact */
  160.        do {
  161.           printf ("Enter encoded file name <required>: ");
  162.           gets (encoded_file_name);
  163.           if (encoded_file_name[0] == NULL_CHAR)
  164.              printf ("Encoded file name is required. \n");
  165.        } while (encoded_file_name[0] == NULL_CHAR);
  166.        printf (">>> Encoded file name is: %s \n", encoded_file_name);
  167. #ifdef  MS_DOS
  168.        printf ("Enter MPEG decoded file name <%s>: ",
  169.                new_ext(encoded_file_name, DFLT_OPEXT)); /* 92-08-19 shn */
  170. #else
  171.        printf ("Enter MPEG decoded file name <%s%s>: ", encoded_file_name,
  172.                DFLT_OPEXT);
  173. #endif
  174.        gets (decoded_file_name);
  175.        if (decoded_file_name[0] == NULL_CHAR) {
  176. #ifdef  MS_DOS
  177.            /* replace old extension with new one, 92-08-19 shn */
  178.            strcpy(decoded_file_name,new_ext(encoded_file_name, DFLT_OPEXT));
  179. #else
  180.            strcat (strcpy(decoded_file_name, encoded_file_name), DFLT_OPEXT);
  181. #endif
  182.        }
  183.        printf (">>> MPEG decoded file name is: %s \n", decoded_file_name);
  184.  
  185.        printf(
  186.           "Do you wish to write an AIFF compatible sound file ? (y/<n>) : ");
  187.        gets(t);
  188.        if (*t == 'y' || *t == 'Y') need_aiff = TRUE;
  189.        else                        need_aiff = FALSE;
  190.        if (need_aiff)
  191.             printf(">>> An AIFF compatible sound file will be written\n");
  192.        else printf(">>> A non-headered PCM sound file will be written\n");
  193.  
  194.        printf(
  195.           "Do you wish to exit (last chance before decoding) ? (y/<n>) : ");
  196.        gets(t);
  197.        if (*t == 'y' || *t == 'Y') exit(0);
  198.     }
  199.     else {        /* interpret CL Args */
  200.        int i=0, err=0;
  201.  
  202.        need_aiff = FALSE;
  203.        encoded_file_name[0] = '\0';
  204.        decoded_file_name[0] = '\0';
  205.  
  206.        while(++i<argc && err == 0) {
  207.           char c, *token, *arg, *nextArg;
  208.           int  argUsed;
  209.  
  210.           token = argv[i];
  211.           if(*token++ == '-') {
  212.              if(i+1 < argc) nextArg = argv[i+1];
  213.              else           nextArg = "";
  214.              argUsed = 0;
  215.              while(c = *token++) {
  216.                 if(*token /* NumericQ(token) */) arg = token;
  217.                 else                             arg = nextArg;
  218.                 switch(c) {
  219.                    case 's':  topSb = atoi(arg); argUsed = 1;
  220.                       if(topSb<1 || topSb>SBLIMIT) {
  221.                          fprintf(stderr, "%s: -s band %s not %d..%d\n",
  222.                                  programName, arg, 1, SBLIMIT);
  223.                          err = 1;
  224.                       }
  225.                       break;
  226.                    case 'A':  need_aiff = TRUE; break;
  227.                    default:   fprintf(stderr,"%s: unrecognized option %c\n",
  228.                                       programName, c);
  229.                       err = 1; break;
  230.                 }
  231.                 if(argUsed) {
  232.                    if(arg == token) token = ""; /* no more from token */
  233.                    else             ++i; /* skip arg we used */
  234.                    arg = ""; argUsed = 0;
  235.                 }
  236.              }
  237.           }
  238.           else {
  239.              if(encoded_file_name[0] == '\0')
  240.                 strcpy(encoded_file_name, argv[i]);
  241.              else
  242.                 if(decoded_file_name[0] == '\0')
  243.                    strcpy(decoded_file_name, argv[i]);
  244.                 else {
  245.                    fprintf(stderr,
  246.                            "%s: excess arg %s\n", programName, argv[i]);
  247.                    err = 1;
  248.                 }
  249.           }
  250.        }
  251.  
  252.        if(err || encoded_file_name[0] == '\0') usage();  /* never returns */
  253.  
  254.        if(decoded_file_name[0] == '\0') {
  255.           strcpy(decoded_file_name, encoded_file_name);
  256.           strcat(decoded_file_name, DFLT_OPEXT);
  257.        }
  258.  
  259.     }
  260.     /* report results of dialog / command line */
  261.     printf("Input file = '%s'  output file = '%s'\n",
  262.            encoded_file_name, decoded_file_name);
  263.     if(need_aiff) printf("Output file written in AIFF format\n");
  264.  
  265.     if(strcmp(decoded_file_name,"stdout") == 0) musicout = stdout;
  266.     else {
  267.          if ((musicout = fopen(decoded_file_name, "w+b")) == NULL) {
  268.             printf ("Could not create \"%s\".\n", decoded_file_name);
  269.             exit(1);
  270.          }
  271.     }
  272.  
  273.     open_bit_stream_r(&bs, encoded_file_name, BUFFER_SIZE);
  274.  
  275.     if (need_aiff)
  276.        if (aiff_seek_to_sound_data(musicout) == -1) {
  277.           printf("Could not seek to PCM sound data in \"%s\".\n",
  278.                  decoded_file_name);
  279.           exit(1);
  280.        }
  281.  
  282.     sample_frames = 0;
  283.  
  284.     while (!end_bs(&bs)) {
  285.  
  286.        sync = seek_sync(&bs, SYNC_WORD, SYNC_WORD_LNGTH);
  287.        frameBits = sstell(&bs) - gotBits;
  288.        if(frameNum > 0)        /* don't want to print on 1st loop; no lay */
  289.           if(frameBits%bitsPerSlot)
  290.              fprintf(stderr,"Got %ld bits = %ld slots plus %ld\n",
  291.                      frameBits, frameBits/bitsPerSlot, frameBits%bitsPerSlot);
  292.        gotBits += frameBits;
  293.  
  294.        if (!sync) {
  295.           printf("Frame cannot be located\n");
  296.           printf("Input stream may be empty\n");
  297.           done = TRUE;
  298.           /* finally write out the buffer */
  299.           if (info.lay == 2) out_fifo(*pcm_sample, 3, &fr_ps, done,
  300.                                       musicout, &sample_frames);
  301.           else               out_fifo(*pcm_sample, 1, &fr_ps, done,
  302.                                       musicout, &sample_frames);
  303.           break;
  304.        }
  305.  
  306.        decode_info(&bs, &fr_ps);
  307.        hdr_to_frps(&fr_ps);
  308.        stereo = fr_ps.stereo;
  309.        error_protection = info.error_protection;
  310.        crc_error_count = 0;
  311.        total_error_count = 0;
  312.        if(frameNum == 0) WriteHdr(&fr_ps, stdout);  /* printout layer/mode */
  313.  
  314.        fprintf(stderr, "{%4lu}\r", frameNum++); fflush(stderr);
  315.        if (error_protection) buffer_CRC(&bs, &old_crc);
  316.  
  317.        switch (info.lay) {
  318.  
  319.           case 1: {
  320.              bitsPerSlot = 32;        samplesPerFrame = 384;
  321.              I_decode_bitalloc(&bs,bit_alloc,&fr_ps);
  322.              I_decode_scale(&bs, bit_alloc, scale_index, &fr_ps);
  323.  
  324.              if (error_protection) {
  325.                 I_CRC_calc(&fr_ps, bit_alloc, &new_crc);
  326.                 if (new_crc != old_crc) {
  327.                    crc_error_count++;
  328.                    total_error_count++;
  329.                    recover_CRC_error(*pcm_sample, crc_error_count,
  330.                                      &fr_ps, musicout, &sample_frames);
  331.                    break;
  332.                 }
  333.                 else crc_error_count = 0;
  334.              }
  335.  
  336.              clip = 0;
  337.              for (i=0;i<SCALE_BLOCK;i++) {
  338.                 I_buffer_sample(&bs,(*sample),bit_alloc,&fr_ps);
  339.                 I_dequantize_sample(*sample,*fraction,bit_alloc,&fr_ps);
  340.                 I_denormalize_sample((*fraction),scale_index,&fr_ps);
  341.                 if(topSb>0)        /* clear channels to 0 */
  342.                    for(j=topSb; j<fr_ps.sblimit; ++j)
  343.                       for(k=0; k<stereo; ++k)
  344.                          (*fraction)[k][0][j] = 0;
  345.  
  346.                 for (j=0;j<stereo;j++) {
  347.                    clip += SubBandSynthesis (&((*fraction)[j][0][0]), j,
  348.                                              &((*pcm_sample)[j][0][0]));
  349.                 }
  350.                 out_fifo(*pcm_sample, 1, &fr_ps, done,
  351.                          musicout, &sample_frames);
  352.              }
  353.              if(clip > 0) printf("%d output samples clipped\n", clip);
  354.              break;
  355.           }
  356.  
  357.           case 2: {
  358.              bitsPerSlot = 8;        samplesPerFrame = 1152;
  359.              II_decode_bitalloc(&bs, bit_alloc, &fr_ps);
  360.              II_decode_scale(&bs, scfsi, bit_alloc, scale_index, &fr_ps);
  361.  
  362.              if (error_protection) { 
  363.                 II_CRC_calc(&fr_ps, bit_alloc, scfsi, &new_crc);
  364.                 if (new_crc != old_crc) {
  365.                    crc_error_count++;
  366.                    total_error_count++;
  367.                    recover_CRC_error(*pcm_sample, crc_error_count,
  368.                                      &fr_ps, musicout, &sample_frames);
  369.                    break;
  370.                 }
  371.                 else crc_error_count = 0;
  372.              }
  373.  
  374.              clip = 0;
  375.              for (i=0;i<SCALE_BLOCK;i++) {
  376.                 II_buffer_sample(&bs,(*sample),bit_alloc,&fr_ps);
  377.                 II_dequantize_sample((*sample),bit_alloc,(*fraction),&fr_ps);
  378.                 II_denormalize_sample((*fraction),scale_index,&fr_ps,i>>2);
  379.  
  380.                 if(topSb>0)        /* debug : clear channels to 0 */
  381.                    for(j=topSb; j<fr_ps.sblimit; ++j)
  382.                       for(k=0; k<stereo; ++k)
  383.                          (*fraction)[k][0][j] =
  384.                          (*fraction)[k][1][j] =
  385.                          (*fraction)[k][2][j] = 0;
  386.  
  387.                 for (j=0;j<3;j++) for (k=0;k<stereo;k++) {
  388.                    clip += SubBandSynthesis (&((*fraction)[k][j][0]), k,
  389.                                              &((*pcm_sample)[k][j][0]));
  390.                 }
  391.                 out_fifo(*pcm_sample, 3, &fr_ps, done, musicout,
  392.                          &sample_frames);
  393.              }
  394.              if(clip > 0) printf("%d samples clipped\n", clip);
  395.              break;
  396.           }
  397.  
  398.        }
  399.  
  400.     }
  401.  
  402.     if (need_aiff) {
  403.        pcm_aiff_data.numChannels       = stereo;
  404.        pcm_aiff_data.numSampleFrames   = sample_frames;
  405.        pcm_aiff_data.sampleSize        = 16;
  406.        pcm_aiff_data.sampleRate        = s_freq[info.sampling_frequency]*1000;
  407. #ifdef IFF_LONG       
  408.        pcm_aiff_data.sampleType        = IFF_ID_SSND;
  409. #else
  410.        strncpy(&pcm_aiff_data.sampleType,IFF_ID_SSND,4);
  411. #endif
  412.        pcm_aiff_data.blkAlgn.offset    = 0;
  413.        pcm_aiff_data.blkAlgn.blockSize = 0;
  414.  
  415.  
  416.  
  417.        if (aiff_write_headers(musicout, &pcm_aiff_data, decoded_file_name) == -1) {
  418. /*
  419.        if (aiff_write_headers(musicout, &pcm_aiff_data) == -1) {
  420. */
  421.           printf("Could not write AIFF headers to \"%s\"\n",
  422.                  decoded_file_name);
  423.           exit(2);
  424.        }
  425.     }
  426.  
  427.     printf("Avg slots/frame = %.3f; b/smp = %.2f; br = %.3f kbps\n",
  428.            (FLOAT) gotBits / (frameNum * bitsPerSlot),
  429.            (FLOAT) gotBits / (frameNum * samplesPerFrame),
  430.            (FLOAT) gotBits / (frameNum * samplesPerFrame) *
  431.            s_freq[info.sampling_frequency]);
  432.  
  433.     close_bit_stream_r(&bs);
  434.     fclose(musicout);
  435.  
  436.     /* for the correct AIFF header information */
  437.     /*             on the Macintosh            */
  438.     /* the file type and the file creator for  */
  439.     /* Macintosh compatible Digidesign is set  */
  440.  
  441. #ifdef  MACINTOSH
  442.     if (need_aiff) set_mac_file_attr(decoded_file_name, VOL_REF_NUM,
  443.                                      CREATR_DEC_AIFF, FILTYP_DEC_AIFF);
  444.     else           set_mac_file_attr(decoded_file_name, VOL_REF_NUM,
  445.                                      CREATR_DEC_BNRY, FILTYP_DEC_BNRY);
  446. #endif
  447.  
  448.     printf("Decoding of \"%s\" is finished\n", encoded_file_name);
  449.     printf("The decoded PCM output file name is \"%s\"\n", decoded_file_name);
  450.     if (need_aiff)
  451.        printf("\"%s\" has been written with AIFF header information\n",
  452.               decoded_file_name);
  453.  
  454. #ifdef UNIX
  455.     time_to_decode = clock()-time_to_decode;
  456.  
  457.     printf("Total time used to decode the stream was %.2f secs.\n",
  458.     (float)time_to_decode/CLK_TCK);
  459. #endif
  460.  
  461.  
  462.     exit( 0 );
  463. }
  464.  
  465. static void usage()  /* print syntax & exit */
  466. {
  467.    fprintf(stderr,
  468.       "usage: %s                         queries for all arguments, or\n",
  469.        programName);
  470.    fprintf(stderr,
  471.       "       %s [-A][-s sb] inputBS [outPCM]\n", programName);
  472.    fprintf(stderr,"where\n");
  473.    fprintf(stderr," -A       write an AIFF output PCM sound file\n");
  474.    fprintf(stderr," -s sb    resynth only up to this sb (debugging only)\n");
  475.    fprintf(stderr," inputBS  input bit stream of encoded audio\n");
  476.    fprintf(stderr," outPCM   output PCM sound file (dflt inName+%s)\n",
  477.            DFLT_OPEXT);
  478.    exit(1);
  479. }
  480.